package ar.edu.uba.fi.jmit.monitorengine.core;

import ar.edu.uba.fi.jmit.integrationcommons.Event;
import ar.edu.uba.fi.jmit.integrationcommons.EventPriority;
import ar.edu.uba.fi.jmit.monitorengine.Constants;
import ar.edu.uba.fi.jmit.monitorengine.MonitorEngineTestCase;
import ar.edu.uba.fi.jmit.monitorengine.ResourceProperties;
import ar.edu.uba.fi.jmit.monitorengine.mock.MockMonitor1;
import ar.edu.uba.fi.jmit.monitorengine.mock.MockRangeObserver;
import ar.edu.uba.fi.jmit.monitorengine.mock.MonitorEngineSenderMock;

public class RangeObserverTestCase extends MonitorEngineTestCase {
	
	private Monitor monitor;
	private MonitorEngineSenderMock monitorEngineSender;
	
	@Override
	protected void setUp() throws Exception {
		super.setUp();
		monitor = new MockMonitor1();
		monitorEngineSender = new MonitorEngineSenderMock();
	}

	public void testNoBoundExceded() {
		MockRangeObserver rangeObserver = new MockRangeObserver();
		rangeObserver.setMaxValue(100L);
		rangeObserver.setMinValue(50L);
		rangeObserver.setTimeOutOfRangeAllowed(null);
		rangeObserver.setActualMonitorValue(60L);
		rangeObserver.setMonitorEngineSender(monitorEngineSender);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(70L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(80L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(90L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(100L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(50L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
	}
	
	public void testMaxBoundExceded() {
		MockRangeObserver rangeObserver = new MockRangeObserver();
		rangeObserver.setMaxValue(100L);
		rangeObserver.setMinValue(50L);
		rangeObserver.setName("testRange");
		rangeObserver.setAlert(true);
		rangeObserver.setSeverity("This is not a big problem, just a test");
		rangeObserver.setTimeOutOfRangeAllowed(null);
		rangeObserver.setActualMonitorValue(60L);
		rangeObserver.setMonitorEngineSender(monitorEngineSender);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(101L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(1, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(200L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(2, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(1000L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(3, monitorEngineSender.getSendedEvents().size());
		Event event = monitorEngineSender.getLastSendedEvent();
		assertEquals("testRange", event.getSource());
		assertEquals(EventPriority.ALERT, event.getPriority());
		assertEquals("testRange", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_NAME)));
		assertEquals(100L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_EXCEDED_BOUND)));
		assertEquals(1000L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_REGISTERED_VALUE)));
		assertEquals("This is not a big problem, just a test", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_SEVERITY)));
	}
	
	public void testMinBoundExceded() {
		MockRangeObserver rangeObserver = new MockRangeObserver();
		rangeObserver.setMaxValue(100L);
		rangeObserver.setMinValue(50L);
		rangeObserver.setName("testRange");
		rangeObserver.setAlert(true);
		rangeObserver.setSeverity("This is not a big problem, just a test");
		rangeObserver.setTimeOutOfRangeAllowed(null);
		rangeObserver.setActualMonitorValue(60L);
		rangeObserver.setMonitorEngineSender(monitorEngineSender);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(40L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(1, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(-1L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(2, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(10L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(3, monitorEngineSender.getSendedEvents().size());
		Event event = monitorEngineSender.getLastSendedEvent();
		assertEquals("testRange", event.getSource());
		assertEquals(EventPriority.ALERT, event.getPriority());
		assertEquals("testRange", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_NAME)));
		assertEquals(50L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_EXCEDED_BOUND)));
		assertEquals(10L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_REGISTERED_VALUE)));
		assertEquals("This is not a big problem, just a test", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_SEVERITY)));
	}
	
	public void testMaxBoundExcededWithTimeAllowed() throws InterruptedException {
		MockRangeObserver rangeObserver = new MockRangeObserver();
		rangeObserver.setMaxValue(100L);
		rangeObserver.setMinValue(50L);
		rangeObserver.setName("testRange");
		rangeObserver.setAlert(true);
		rangeObserver.setSeverity("This is not a big problem, just a test");
		rangeObserver.setTimeOutOfRangeAllowed(1000L);//1 second
		rangeObserver.setActualMonitorValue(200L);
		rangeObserver.setMonitorEngineSender(monitorEngineSender);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		Thread.sleep(1020L);
		assertEquals(1, monitorEngineSender.getSendedEvents().size());
		Event event = monitorEngineSender.getLastSendedEvent();
		assertEquals("testRange", event.getSource());
		assertEquals(EventPriority.ALERT, event.getPriority());
		assertEquals("testRange", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_NAME)));
		assertEquals(100L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_EXCEDED_BOUND)));
		assertEquals(200L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_REGISTERED_VALUE)));
		assertEquals("This is not a big problem, just a test", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_SEVERITY)));
	}
	
	public void testMaxBoundExcededWithTimeAllowed2() throws InterruptedException {
		MockRangeObserver rangeObserver = new MockRangeObserver();
		rangeObserver.setMaxValue(100L);
		rangeObserver.setMinValue(50L);
		rangeObserver.setName("testRange");
		rangeObserver.setAlert(true);
		rangeObserver.setSeverity("This is not a big problem, just a test");
		rangeObserver.setTimeOutOfRangeAllowed(2000L);//2 seconds
		rangeObserver.setActualMonitorValue(200L);
		rangeObserver.setMonitorEngineSender(monitorEngineSender);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		Thread.sleep(1000L);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		Thread.sleep(1010L);
		assertEquals(1, monitorEngineSender.getSendedEvents().size());
		Event event = monitorEngineSender.getLastSendedEvent();
		assertEquals("testRange", event.getSource());
		assertEquals(EventPriority.ALERT, event.getPriority());
		assertEquals("testRange", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_NAME)));
		assertEquals(100L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_EXCEDED_BOUND)));
		assertEquals(200L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_REGISTERED_VALUE)));
		assertEquals("This is not a big problem, just a test", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_SEVERITY)));
	}
	
	public void testMaxBoundExcededWithTimeAllowed3() throws InterruptedException {
		MockRangeObserver rangeObserver = new MockRangeObserver();
		rangeObserver.setMaxValue(100L);
		rangeObserver.setMinValue(50L);
		rangeObserver.setName("testRange");
		rangeObserver.setAlert(true);
		rangeObserver.setSeverity("This is not a big problem, just a test");
		rangeObserver.setTimeOutOfRangeAllowed(2000L);//2 seconds
		rangeObserver.setActualMonitorValue(200L);
		rangeObserver.setMonitorEngineSender(monitorEngineSender);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		Thread.sleep(1000L);
		rangeObserver.setActualMonitorValue(100L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		Thread.sleep(1001L);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		Thread.sleep(1001L);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(1000L);
		rangeObserver.onMonitorChange(monitor);
		Thread.sleep(2010L);
		assertEquals(1, monitorEngineSender.getSendedEvents().size());
		Event event = monitorEngineSender.getLastSendedEvent();
		assertEquals("testRange", event.getSource());
		assertEquals(EventPriority.ALERT, event.getPriority());
		assertEquals("testRange", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_NAME)));
		assertEquals(100L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_EXCEDED_BOUND)));
		assertEquals(1000L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_REGISTERED_VALUE)));
		assertEquals("This is not a big problem, just a test", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_SEVERITY)));
	}
	
	public void testMaxBoundExcededWithTimeAllowed4() throws InterruptedException {
		MockRangeObserver rangeObserver = new MockRangeObserver();
		rangeObserver.setMaxValue(100L);
		rangeObserver.setMinValue(50L);
		rangeObserver.setName("testRange");
		rangeObserver.setAlert(true);
		rangeObserver.setSeverity("This is not a big problem, just a test");
		rangeObserver.setTimeOutOfRangeAllowed(2000L);//2 seconds
		rangeObserver.setActualMonitorValue(200L);
		rangeObserver.setMonitorEngineSender(monitorEngineSender);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		Thread.sleep(1000L);
		rangeObserver.setActualMonitorValue(100L);
		rangeObserver.onMonitorChange(monitor);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		Thread.sleep(1001L);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		rangeObserver.setActualMonitorValue(100L);
		rangeObserver.onMonitorChange(monitor);
		rangeObserver.setActualMonitorValue(1000L);
		rangeObserver.onMonitorChange(monitor);
		Thread.sleep(1001L);
		assertEquals(0, monitorEngineSender.getSendedEvents().size());
		Thread.sleep(1010L);
		assertEquals(1, monitorEngineSender.getSendedEvents().size());
		Event event = monitorEngineSender.getLastSendedEvent();
		assertEquals("testRange", event.getSource());
		assertEquals(EventPriority.ALERT, event.getPriority());
		assertEquals("testRange", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_NAME)));
		assertEquals(100L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_EXCEDED_BOUND)));
		assertEquals(1000L, event.getData().get(ResourceProperties.getProperty(Constants.RANGE_REGISTERED_VALUE)));
		assertEquals("This is not a big problem, just a test", event.getData().get(ResourceProperties.getProperty(Constants.RANGE_SEVERITY)));
	}
	
	
}
